home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48hor2
/
rpl48.doc
< prev
next >
Wrap
Text File
|
1995-03-31
|
69KB
|
1,706 lines
##### ##### # # ###
# # # # # ## # #
# # # # # # # # #
#### #### # # # ###
# # # # ##### # #
# # # # # # #
# # # #### # ###
A SYSTEM-RPL DEVELOPMENT TOOLKIT FOR THE HP48SX
Version 1.12 beta
(c) 1993 by Detlef Mueller & Raymond Hellstern
CONTENTS
========
1. Introduction
1.1 Copyrights & Acknoledgements
1.2 The RPL48 Toolkit
1.3 Requirements & Installation Instructions
1.4 Abbreviations
2. <-RPL-> Library
2.1 Overview
2.2 The System-RPL Compiler/Decompiler
2.3 The Saturn Assembler/Disassembler
2.3.1 The Assembler Parameter Field Parser
2.4 The Reference Table
2.5 Command Reference
2.6 Hooks
2.7 Things to Notice
3. <-LIB-> Library
3.1 Overview
3.2 Control Variables
3.3 Command Reference
3.4 Things to Notice
Appendix A - Quick Reference Guides
A.1 <-RPL->
A.1.1 Commands
A.1.2 Flag Usage
A.1.3 Error Messages
A.2 <-LIB->
A.2.1 Commands
A.2.2 Flag Usage
A.2.3 Error Messages
Appendix B - A ->COD Example
Appendix C - Ordering Information
1. Introduction
===============
1.1 Copyrights & Acknowledgements
---------------------------------
All files of the RPL48 toolkit are copyrighted (c) by Detlef Mueller and
Raymond Hellstern, 1991-1993 - unless otherwise noted.
The RPL48 package is distributed in the hope that it will be useful, but
RPL48 is provided 'as is,' and is subject to change without notice.
D. Mueller and R. Hellstern makes no warranty of any kind with regard to
the software or documentation, including, but not limited to, the implied
warranties of merchantability and fitness for a particular purpose.
D.Mueller and R.Hellstern shall not be liable for any error or for incidental
or consequential damages in connection with the furnishing, performance, or
use of this software and documentation.
Please excuse all the linguistic errors in this text. English is not our
native language.
This version of RPL48 is a GiftWare release - you may use it as long as you
like - without registration for developing non-commercial software only.
Permission to copy the whole, unmodified RPL48 package is granted provided
that the copies are not made or distributed for resale (excepting nominal
copying fees). If you want to get your own, brand new version and for further
information please refer to Appendix C.
It should be impossible to crash your HP48 by using RPL48, but no software is
bug free and the <-RPL->:4.1 library (serial no. 113) is still a beta release.
We would like to thank the following persons for their support:
Wlodek Mier-Jedrzejowicz for presenting RPL48 to the world.
Rick Grevelle for the HACKIT library, the ->DIR command in the <-LIB->
library, the base of the sys-stack, many suggestions and exiting talks.
Mika Heiskanen for beta testing, lots of suggestions, MKROM and DEBUG.
Joseph K. Horn for beta testing and suggestions, the `HP 48 Resource
Allocation Guideline; Library ID's`, SORTLS and for maintaining the
HP48 Goodies Disks.
Carlos Ferraro for beta testing.
Simone Rapisarda for beta testing and many suggestions.
Fatri Mohamed, Romain Desplats, Georg Hoppen for suggestions and beta
testing.
James H. Cloos, Steve VanDevender, Chris Maksymiak for suggestions.
Chris Spell for maintaining the HP48 archive at seq.uncwil.edu and for
moderating comp.sources.hp48.
W.C.Wickes & HP Corvallis for the HP48 and the RPL tools.
D. York for the friendly permission to publish the BNF parser generator
example.
1.2 The RPL48 Toolkit
---------------------
The RPL48 Toolkit provides more than 50 powerful commands to aid program and
library development on a HP48 using system RPL and assembler. It consists of
three parts:
- Library 1234, <-RPL->:4.1 - Contains a sys-RPL compiler/decompiler and
Saturn assembler/disassembler.
- Library 1221, <-LIB->:1.7 - Contains a library maker/splitter and many
commands for handling libraries and un-/supported objects.
- a reference table which contains addresse/name pairs of ROM entry points.
The main commands of RPL48 are modelled after the MS-DOS programs RPLCOMP.EXE,
SASM.EXE and USRLIB.EXE which are provided by HP in the self extracting
archive TOOLS.EXE (available on several ftp sites). This document describes
the interface to RPL48; it is not a sys-RPL or Saturn assembler manual. Please
refer to RPLMAN.DOC, RPLCOMP.DOC, USRLIB.DOC and SASM.DOC (all contained in
TOOLS.EXE) for learning and/or reference purposes. [Note: RPLMAN.DOC etc can
be found on Goodies Disk #4. -jkh-]
We assume that you are familar with sys-RPL, Saturn assembler and libraries.
1.3 Requirements & Installation Instructions
--------------------------------------------
RPL48 runs on ROM version A-E HP48SX; it may run on ROM version J, but it is
not tested yet !
The <-RPL-> library it compiled to a fixed address; it MUST be stored in an
independent (FREEd) port (1 or 2) - thus it only works on a HP48SX. Because
the whole RPL48 kit requires ~60kb of memory (including a reference table made
from the latest entries released by HP) it is recommended to store it into a
128k RAM card. The <-LIB-> library is developpt using the standard methods,
it can be stored and used in port 0 on a HP48S.
For a complete installation of RPL48 it is neccessary that you have plugged in
a 128k RAM card (which must have ~60kb free space) in either port 1 or 2 of
your HP48SX; the card must be set to R/W. Proceed as follows:
- remove any old versions
- merge the port
- download RPL.TAB, LIB.LIB and RPL.LIB
- recall RPL.TAB to the stack, purge RPL.TAB and store it as a backup
object named RPL.TAB (case sensitive !) into port 0 (:0:RPL.TAB STO)
- recall the two libraries, purge the variables containing the original
copies and store the libraries into port 0 (two times 0 STO)
- free the port, make sure that :0:1234 is the 1st entry of the list in
level 2 for the FREE command ! (you can use 0 PVARS DROP to generate the
base list)
- power cycle your HP48SX or press [ON]-[C]
As mentioned, <-RPL-> is compiled to an absolute address. Its config code
takes care of the address the library is stored at. If neccessary, the base
addresses of the ports are swapped and an additional warmstart is initiated
automatically while executing the first warmstart after installation. If the
config code recognizes that it is impossible to change to the correct address
(ie. the library is stored in port 0 or not the 1st object of port 1 or 2),
the autoattach to the home directory is supressed and no (c)-message and no
beep is generated. If the library did not attach itself, make sure it becomes
the 1st object of port 1 or 2 and execute a warmstart again.
If you have installed a HP41 emulator card, <-RPL-> does not install because
the emulator uses a similar scheme to install itself to the same address (it
is also an absolute library) -- just remove the card.
The <-RPL-> and the <-LIB-> libraries are not self-modifing - you can write
protect the card containing the libraries.
1.4 Abbreviations
-----------------
LID - library id; a number in the range 0..2047, part of any library, It is
used by the HP firmware to identify libraries while resolving commands,
messages et c.
| - used in stack diagrams for 'or'
Abbreviations denoting objects:
ob object of any type
xlib named or unnamed library command
:x:y tagged object - tag x, ob y
prg program (secondary)
bak backup
dir directory
alg algebraic
lib library
libdta library data
meta(t) meta object, obn .. ob1 %n, all ob's are of the same type t
All other abbreviations are defined in RPLMAN.DOC (eg. %, #).
2. <-RPL-> Library
==================
2.1 Overview
------------
<-RPL-> contains 17 commands, including a sys-RPL compiler (->RPL), a sys-RPL
decompiler (RPL->), a Saturn assembler (->COD), a Saturn disassembler (COD->)
a RPL.TAB browser (EC) and a medium font sys-stack display (4/5/7).
2.2 The System-RPL Compiler/Decompiler
--------------------------------------
The compiler is a simple token based one pass LR compiler and implements a
grammatical subset of RPLCOMP.EXE. It accepts string objects containing a
token sequence as input. Tokens must be seperated by whitespace (NL,CR,Space,
TAB etc.).
The output of the decompiler can be used as input for the compiler or (with
minor modifications) as input for RPLCOMP.EXE.
When ->RPL is compiling a string, it recognizes certain words and generates
appropriate code for them. All other words are assumed to be the labels of
objects in the runstream and are emitted simply as 5-nibble constants - the
reference table (see below) and the assembler symbol table are searched to
resolve the appropriate 5-nibble addresses. If an entry can't be found in one
of the tables and its 1st chararcter is a 'x', then ->RPL will try to resolve
the word without the leading 'x' as a built-in command (e.g. for 'xDROP' the
address #1FBD8 is generated).
If the current token of ->RPL isn't resolvable as an object, entry or built
in, it is passed to the user-RPL compiler palparse. If the result is an ID or
prg, an error will be generated. If the token is parsed to a %, it will be
converted to a # (eg. "12345" ->RPL --> <3039h> (negative values are mapped
to 0 and fractional parts are ignored)); any other valid object is simply
added to the runstream (eg. [[1,2][3,4]] (F(.)) inserts a 2*2 array of reals).
The following words are recognized by ->RPL or generated by RPL->:
LAM <id>
DOLAM object whose name is specified by <id>. (1)
ID <id>
DOIDNT object whose name is specified by <id>. 0-ID isn't supported by
->RPL. (1)
TAG <id> <ob>
DOTAG object whose tag is specified by <id> and whose object is given
by <ob>.
$ "string"
DOCSTR object with the contents contained between the quotes. (1)
CHR <char>
DOCHAR object with the specified character. (1)
# <hex no>
#<hex no>
DOBINT object whose body is the number specified in hex. (3)
% <real no>
DOREAL object with the specified floating-point number.
%% <extended real no>
DOEREL object with the specified floating-point number. The number is
parsed with % resolution.
C% <real no> <real no>
DOCMP object with the specified floating-point numbers.
C%% <extended real no> <extended real no>
DOECMP object with the specified floating-point numbers. The numbers are
parsed with % resolution.
PTR <hex #>
Forces the <hex #> to be entered as a runstream pointer-obj.
ROMPTR <hex #> <hex #>
DOROMP object with the two 3-digit (maximum) hex numbers.
HXS <length in hex> <string>
GROB <length in hex> <string>
CODE <length in hex> <string> (2)
ARRY <length in hex> <string> (2)
LNKARRY <length in hex> <string> (2)
LIBRARY <length in hex> <string> (2)
BACKUP <length in hex> <string> (2)
LIBDAT <length in hex> <string> (2)
EXT1 <length in hex> <string> (2)
EXT2 <length in hex> <string> (2)
EXT3 <length in hex> <string> (2)
EXT4 <length in hex> <string> (2)
Specified object whose body is made from the hex-string. 0-ob's aren't
supported by ->RPL.
NIBB <length in hex> <string> (2)
Adds the binary form of <string> to the runstream, eg. NIBB 7 84E2000
creates a 0-ID.
CODE <assembler source ..> ENDCODE
CODE object, the assembler is called to assemble the body.
ASSEMBLE <assembler source ..> RPL
The assembler is used to create the inline code.
INCLUDE <name>
The accessable path is searched for a variable with the name <name>. Its
contens must be a compilable string and may contain further INCLUDE
statements. The resulting code is inserted at the position of the INCLUDE
statement.
INCLOB <name> (2)
The accessable path is searched for a variable with the name <name>. Its
recalled contens is inserted at the position of the INCLOB statement.
The following words defines runstream pointer-objects:
UNIT DOEXT - Unit start
SYMBOL 02AB8 - Symbolic start
:: DOCOL - Program start
{ DOLIST - List start
} SEMI - List terminator
; SEMI - Program, UNIT or SYMBOL terminator
Text surrounded by ' (' and ') ' is ignored by ->RPL.
Before you start compiling own objects, play with the decompiler to get some
examples of the syntax definitions, eg. try { + } 1 GET RPL-> to see what '+'
does.
Note (1)
Character substitution is supported via '\xxx' in strings, IDs, LAMs and
CHRs using the internal routine which does the tranlsation for TRANSIO,
code 3 (see the HP48 manual for a comlete description). You must use
'\034' to insert doublequotes (") into strings.
RPL-> generates (") within strings, not \034.
Note (2)
These statements are not compatible to RPLCOMP.EXE.
Note (3)
->RPL accepts BINTS in one of the following form:
# xxx - allways compiled to BINT objects
#xxx - searches the ROM for a BINT with the appropriate value, if
found a pointer to is generated instead of a BINT object
xxx - real numbers are COERCED and then handled like #xxx
2.3 The Saturn Assembler/Disassembler
-------------------------------------
The assembler defines a subset of SASM.EXE written by Nathan Zelle. You can
use it 'stand-alone' or in conjunction with the RPL compiler ->RPL. It's a
2-pass assembler.
The input string should be plain ASCII (with blanks and/or TAB's) generated on
a PC or the HP48 itself.
It is 'free format' which means that no coloumn counting is required, except
that labels MUST begin in the first coloumn of a line.
If a line only consists of a comment, in coloumn 1 MUST be a '*'. Empty lines
are skipped.
The general line structure is: "<Label> [<Mnemonic> <Modifier> <Comment>]" or
"* Comment"; the fields are seperated by blanks or TABs.
Most parameters can be symbolic (eg. " GOVLNG (=SAVPTR)+45*3" is valid).
The assembler supports 'conditional assembly' as well as defining equates via
"Label EQU expression". Please refer to SASM.DOC for more details.
You can call 'global' entry points, if a reference table is installed.
A predefined standard macro named LOOP is also included. If entered as
mnemonic (without parameter) it will be assembled to " GOVLNG =Loop", an
address which simply does
=Loop A=DAT0 A
D0=D0+ 5
PC=(A)
If the assembler source don't contain any code, the 2nd pass is skiped to
speed up RPL define like constructs - eg. a directory may hold along with
the source strings a variable HEADER:
(HEADER)
ASSEMBLE
@a EQU =1GETLAM
!a EQU =1PUTLAM
@b EQU =2GETLAM
!b EQU =2GETLAM
nr EQU =TWO
RPL
which may be included by a source like:
(xyz)
INCLUDE HEADER
::
CKN
DUP nr #<> case SETSIZEERR
' NULLLAM nr NDUPN {}N BIND
@a @b 2DUP EQUAL ?SWAP
!b !a
(...etc...)
ABND
;
2.3.1 The Assembler Parameter Field Parser
------------------------------------------
Parameter fields are parsed by an expresion parser that is defined as follows:
expr : expr op1 term | term
term : term op2 fact | fact
fact : '(' expr ')' | op3 fact | '(' '=' entry ')' | '(' symbol ')' | num
op1 : '+' | '-' | '!' | '|' | '^'
op2 : '*' | '/' | ':'
op3 : '-' | '"'
num : real-number | '#' hxs-number
entry : label of RPL.TAB
symbol : label of the assembler symbol table
op action
-- ------
* multiply
/ divide
: modulo
" ones complement
- subtract / twos complement
+ add
! bit AND
| bit OR
^ bit XOR
A complete expr must not contain whitespace chars. If an expression consists
only of a '#' number, an entry or a symbol, the parenteses aren't neccessary
(eg. @n EQU =1GETLAM ). Real numbers are converted internally to HXS numbers,
the accuracy is 64 bit. Parsing real numbers and hex numbers is done by the
'48 internal real/hex parser. The expr/term/fact parser are using the solver
token type table.
Expressions of EQU parameter fields must resolve to the requested number
during the 1st assembler pass; they are ignored in the 2nd pass.
2.4 The Reference Table
-----------------------
RPL->, ->RPL, COD->, ->COD, EC, E<->A and 4/5/7 are looking for a reference
table named RPL.TAB which will be used to resolve names and addresses of ROM
entry points. It may be stored in a variable, as a backup object in any port
or as a library command. If RPL.TAB exists, its recalled contens will be
evaluated and if the result is a string starting with '\000\010' it will be
used as a reference table. It is recommended to use the table shipped with
RPL48; it is made using the latest entries list released by HP as database -
double named entries are removed and a few user-RPL names are added to avoid
conflicts when decomling different '->', '>>', 'END' et c.
For generating own tables use GENTAB.C, also shipped with RPL48.
The following example (HP terminology) outlines the structure of a reference
table:
ASSEMBLE
CON(5) =DOCSTR String prologue
REL(5) TabEnd Length field
NIBASC '\00\n' Reference table identifier
* A hash table, for each char from ' '-DEL
* a 5-nib offset into the table
CON(5) 0 ' ' entry, empty
REL(5) _!_ relativ offset to words starting with '!'
CON(5) 0 '"' entry, empty
* ... '#' - 'C'
REL(5) _D_ 'D' entry
* ... 'E' - '}'
CON(5) 0 '~' entry, empty
CON(5) TabEnd DEL entry, always TabEnd
_!_
CON(6) #9623A0
NIBASC `!!append$`
* ...
_D_
* +------- Lenght of the label in bytes.
* | A label can't be > 15 chars in size.
* |+++++-- Address associated to the label, here 074E4
* ||||||
CON(6) #6074E4 Address/length field of the following
NIBASC 'DOBIND' Label
TabEnd
RPL
2.5 Command Reference
---------------------
RPL-> ( ob --> $ )
Decompiles an object into a string. The string can be used as input for
->RPL without modifications (most times).
->RPL ( $ --> ob )
Compiles the input string into an object.
DCADR ( hxs[adr] --> $ hxs[adr]' )
Decompiles the object referenced by the address adr into a string in
level 2 and increment the address by the object size.
COD-> ( code --> $ )
Disassembles a code object, generates HP styled mnemonics. The reference
table is searched for addresses of GO and Dx=(5) mnemonics. The string
can be used as input for ->COD without modifications (most times).
->COD ( $ --> code LibDat )
Assembles a code object. LibDat is the compressed form of a cross
reference listing, use SYM-> (see below) for decompression.
->OB ( hxs[adr] --> ob )
( #adr --> ob )
( XLIB --> ob )
( ob --> ob' )
Input Action
----- ------
hxs Build a pointer, pointing to the address given by the value
of hxs[adr].
# Same as for hxs, except if the value of # points to a valid
ob in the hidden ROM; in this case the object is copied into
TEMPOB. Eg. "# 72000" ->RPL ->OB returns the message table
of the internal library 0.
XLIB Does a rompointer recall.
ob Unconditionally TOTEMPOB.
DAN ( hxs[adr] %n --> $1 .. $n hxs[adr]' )
Disassembles n instructions starting at address hxs[adr].
DA1 ( hxs[adr] --> $ hxs[adr]' )
Disassembles the instruction at address hxs[adr].
DAXY ( hxs[start] hxs[end] --> $ )
Disassembles until the actual adr. is > hxs[end], starting at address
hxs[start].
SYM-> ( LibDat --> $ )
Converts the cross reference table produced by ->COD into a string.
$-> ( $ --> ob )
Converts a hex-dump to an object.
->$ ( ob --> $ )
Generates a hex-dump of an object.
EC ( --> ? )
Entries Catalog - the reference table browser. Errors if no RPL.TAB
can be found.
When starting EC the first time, it'll create the variable ECpar in
the HOME directory. It contains a HXS that is used by EC as a lookup
table into RPL.TAB; you may store the variable into a port (like
RPL.TAB). Any time you install a new reference table it is neccessary
to purge ECpar !
Active keys in the main display of EC:
UP - move scroll bar up one word
DOWN - move scroll bar donw one word
ENTER - push highlighted word as $ onto the stack. If EC is launched
from a command/edit line, ENTER coppies the word into the
editline starting at the current cursor position
NXT - scan for next occurence of the SCAN word. Doesn't scan the
current page
ON - exit EC or cancel sub-action
OFF - turn off
Menu keys:
PG|^ - page up
PG|v - page down
SCAN - prompts for a $ to search, ENTER starts searching. If
EC is launched from a command/edit line, the prompt looks
suspicious, but its functionality is the same
A-Z - try it
ADR? - displays the address of the current word. A 'r' behind the
address marks RPL entries. Words not marked are propably
for use within assembler only. If EC is launched from a
command/edit line, this function is disabled.
A->ST - push the address of the current word onto the stack. If EC is #
launched from a command/edit line, this function is disabled.
For use of EC within a normal edit line, append the following program to
your CST variable and launch EC with CST EC:
:: TakeOver ROMPTR 4D2 C (EC) ;
E<->A ( hxs[adr] | $name --> $name | hxs[adr] )
Searches the reference table for a name or address of a given address or
name.
RPLtab ( --> $ )
Tries to recall the ref. table via RPL.TAB. If no table is found, a
zero-length string is returned.
4/5/7 ( --> )
Starts the medium font sys-stack display in five line mode. Pressing
4/5/7 in five line mode switches to seven line mode, in seven line mode
the sys-stack is canceled.
The following actions are redefined while the 5/7 stack is active:
- pressing the up arrow without an active edit/commandline starts a
5/7 level interactive sys-RPL stack
- pressing the down arrow without an active edit/commandline starts
editing the object of stack level one in sys-RPL syntax
If you have flag -29 set, the i-stack allows you to edit objects in
sys-RPL syntax when pressing the EDIT menu key.
YOU MUST NOT MOVE THE <-RPL-> LIBRARY WHILE 4/5/7 IS ACTIVE !!
(ie. DON'T MERGE THE PORT WHERE <-RPL-> IS STORED WITH AN ACTIVE 4/5/7 !!)
Clear flag -27 to quit 4/5/7 if you want to purge/move <-RPL->.
CC ( --> ? )
Character set Catalog. CC displays a map of 128 characters in the small
font along with some more information for the highlighted char. You can
move through the map with the cursor keys. If you hold down one of the
cursor keys, it will repeat until you release. The ON-key exits the
program, BLUE-ON turns the calc off and ENTER fetches the char number
(tagged with the char) to the stack.
There are three menu keys available:
SWAP - swaps between the upper/lower half of the char set
BIN - toggles the char code display from real/hex to binary and back
EXIT - leaves CC
If you launch CC within an active editline (eg. via the CST menu), ENTER
will copy the highlighted character into the editline to the current
cursor position. For use of CC within a normal edit line, append the
following program to your CST variable and launch CC with CST CC:
:: TakeOver ROMPTR 4D2 10 (CC) ;
2.7 Hooks
---------
There are a few user hooks in <-RPL->, each an unnamed ROMPTR.
ROMPTR 4D2 13 ( --> )
Switches to ADISP and displays a 5/7 level sys-RPL stack.
ROMPTR 4D2 14 ( --> )
Errors if <-RPL-> isn't ATTACHed to the HOME directory.
ROMPTR 4D2 15 ( ob --> $ )
Decompiles an object in quiet mode, eg. for editing.
ROMPTR 4D2 16 ( $ --> )
Compiles a string in quiet mode, eg. after editing.
2.7 Things to Notice
--------------------
->RPL maintains a global assembler symbol table while compiling an object, ie.
it is possible to jump backward from a code object to a previous one:
::
CODE
Lp LOOP
ENDCODE
CODE
GOTO lp
ENDCODE
;
->RPL tries to resolve a token in the following order:
1. check for atomic object (eg. %, # et c.)
2. search reference table
3. search symbol table
4. check for #<hex-no>
5. check for user-RPL word
6. check for user-RPL object
The search of the symbol table enables the programmer to use DEFINE like
constructs:
::
ASSEMBLE
@val EQU =1GETLAM
!val EQU =1PUTLAM
RPL
ONE 1LAMBIND
@val #1+ !val
1GETABND
;
3. <-LIB->
==========
3.1 Overview
------------
<-LIB-> contains 39 commands, including a library maker (D->LIB), a library
splitter (L->DIR), commands to handle any sort of composite objects and
commands to manage libraries.
Libraries are very usefull objects to extend the command set of a HP48 in
a 'native' manner, but unfortunately library creation is not supported by
the HP48 firmware. The HP tools package contains the program USRLIB.EXE,
which provides library creation on a PC; if you want to put your most often
programs into a library (because of easier handling and to keep your VARs
area clean), you have to collect them into a subdirectory, add a few control
variables, transfer the directory in binary form to a PC, run USRLIB.EXE on
it and transfer the created library back to your HP48, where you can install
and test the library.
<-LIB-> provides the command D->LIB that works on the currently active
directory, allowing you to create a library from a directory on the HP48
itself - no transfers, no PC and no USRLIB.EXE are required.
The input directory stucture of D->LIB is modeled very similar to the
directory structure required by USRLIB.EXE, thus existing USRLIB.EXE input
can be used for a library creation with minor changes (the difference is
the format of the $MESSAGE control variable, see below).
3.2 Control Variables
---------------------
The library creation process is controlled by some variables with reserved
names and only the current directory is searched for its presence (note:
multiple occurences of these names are ignored, but only the contens of the
1st one found in the current directory is used for the library creation
process):
$ROMID
Must contain a real or binary number representing the LID that is to
be given to the library. The LID must be in the range 0..2047. Negative
real numbers are mapped to 0.
This is the only control variable that MUST exist in the current
directory !
$TITLE
Should contain a character string to be used as the name of the library
(note: any other object than a string is converted to a string).
The first few characters of the name are displayed in the LIBRARY menu
label associated to the library, the first 22 characters are displayed
by pressing REVIEW in the LIBRARY menu. If $TITLE is absent or contains
an empty string, no title is generated and the resulting library don't
have a menu label in the LIBRARY menu (note: you can switch to the
libraries command menu by executing %LID MENU, even the library don't
have a name or is not attached).
$CONFIG
Must contain a program to be executed at configuration time.
The configuration code can generally NOT be written in user-RPL, but
simple programs such as \<< 123 ATTACH \>> are Ok - more complicated
programs should take care to leave the stack unchanged, and be sure
NOT TO ERROR ! An error in a configuration program will cause a warmstart;
the configuration code is called again during the startup process,
producing a new error etc. If you are accidentally trapped by this, you
must clear your memory to remove the faulty library !
$MESSAGE
Must contain a list of strings to be combined into a message table (note:
any other objects than strings are converted to strings). The message
numbers corresponds to the list positions. In user-RPL you can generate
errors with own messages in the following manner:
#32001h DOERR
|||++-- Message number (here 1)
+++---- LID (here #320h = 800)
In sys-RPL you can use
# 32001 ERROROUT
In this example an error is generated, using the first message from the
message table of a library with the LID 800.
Note: The message list structure is NOT compatible to USRLIB.EXE.
$VISIBLE
Must contain a list of names of variables to be converted to user-
accessible, named library commands. By default, all variables will be
translated to named library commands. When the $VISIBLE list is present,
only the names in this list are included in the library hash table. An
empty list is Ok, meaning that no hash table is generated.
$HIDDEN
Must contain a list of names of variables that are to be converted to
unnamed objects in the library. When the $HIDDEN list is present, those
names listed are not entered in the library hash table. If both $VISIBLE
and $HIDDEN are present, only $HIDDEN will be used.
Note: all visible commands appears as labeled softkeys in the menu
associated to the library, all hidden command not and there is no way
to access them from users scope.
$VARS
Must contains a list of variables that should remain RAM-based - ei. the
objects of the variables listed in $VARS are not included in the library
and no XLIB pointers are made to substitute their names. All other
variables of the current directory are included in the library.
Note: You should add all subdirectory names of the current directory to
the list.
$ROMID must exist in the current directory, all other control variables are
optional - you can generate libraries containing only a configuration program
or a message table. All control variables are internally handled by D->LIB to
be $VARS and can't be accessed from within the library commands.
3.4 Command Reference
---------------------
D->LIB ( --> lib )
Dir to lib; assembles a library from the objects of the current directory.
The creation process is controlled by a few variables with reserved names
(see '3.3 Control Variables').
If you set flag -13 before running D->LIB, it'll switch off the screen
while working (for saving time and batteries).
L->DIR ( %LID --> dir )
( xlib --> ob )
Lib to dir; if the argument is a LID then L->DIR assembles a directory
containing all commands of this library as variables. The neccessary
control variables (see 3.3) are also generated. L->LIB may be used to
recreate the library.
If the argument is a XLIB, then L->DIR recalls its object from the
associated library onto the stack.
If you set flag -13 before running L->DIR on a library, it'll switch off
the screen while working (for saving time and batteries).
Note: You cannot use L->DIR to split <-LIB->, this should prevent users
from a memory lost. If you are conform with the internals of your HP48,
use 'ROMPTR@' (or ->OB) to extract single routines from <-LIB->, but
beware of starting the routines in RAM, most of them will crash your calc
when running standalone !
MCFG ( --> )
Make config; stores a configuration program into a variable named
'$CONFIG' into the current directory. This configuration program will
attach the generated library to the home directory at warmstarts (ON-C
etc.).
'$ROMID' must exist in the current directory.
ML->D ( --> prg )
Generates a program with the following interface:
( {} --> libdta )
The list can contain anything. The program checks for argument count and
type and may error with:
#201 - To Few Arguments - nothing on the stack
#202 - Bad Argument Type - not a list on the stack
'$ROMID' must exist in the current directory.
MD->L ( --> prg )
Generates a program with the following interface:
( libdta --> {} )
The program checks for argument count, type and correct LID and may error
with:
#201 - To Few Arguments - nothing on the stack
#202 - Bad Argument Type - no library data on the stack
#203 - Bad Argument Value - the libdta wasn't created by this lib
'$ROMID' must exist in the current directory.
Note: Store the programs generated by ML->D and MD->L into variables in
your source directory and use them as an interface to generate/resolve
data associated to the resulting library.
OB-> ( prg --> ob1 .. obn %n )
( xlib --> %LID %objno )
( arry --> ob1 .. obn { %di .. %d1 } )
( alg --> ob1 .. obn %n )
( dir --> ob1 id .. obn id %n )
( id --> $ )
( libdta --> {} %LID )
( bak --> ob id )
( id --> $ )
( ob --> dispatch to OBJ-> )
OB-> is an extension to the built-in OBJ->, supporting system level
objects.
->DIR ( ob1 id1 .. obn idn %n --> dir )
->PRG ( ob1 .. obn %n --> prg )
->XLIB ( %LID %cmdno --> xlib )
( #LID #cmdno --> xlib )
->ARR ( ob1 .. obn %n --> arry )
( ob1 .. obn { %di .. %d1 } --> arry )
->ALG ( ob1 .. obn %n --> prg )
->LD ( {} %LID --> libdta )
->BAK ( ob id --> bak )
->ID ( $ --> id )
Functions to reverse OB->.
About ->ARR:
Generates arrays of any type and any dimension (eg. a four dimensional
array of libraries :-).
%di * .. * %d1 must be = n, ob1 .. obn must be of the same type.
All possible parameter errors are trapped.
ADRp ( ob --> ob #addr )
Get address of ob.
Note: The data stack is a stack of pointer to objects. ADRp simply returns
the value from the top element (about the 'p', see 'LIBp' below).
$romid
$visible
$title
$config
$vars
$hidden
$message ( --> '$XXX' )
These commands just put a control variable name onto the stack.
LBCRC ( lib --> lib' )
( bak --> bak' )
Recalculates the CRC of a library or backup, usefull if you have patched
it because modifying the body of a library or backup invalidates the CRC
included at the end of the body.
RNLIB ( lib $ --> lib' )
Renames a library, ie. changes title.
CHLID ( lib % --> lib' )
Change LID; this program allows you to change the LID of a library if
it's not splittable.
Note: Most time a LID is also hardcoded in the config code - this can
generally not be changed by CHLID. You have to attach the library manually
after a warmstart. Also any library have its LID coded in a field above
any visible command (the error handling system identifies the command
that caused an error using this field (the sys-RPL commands 'CKn' copies
this values to the appropriate location)). These fields are not changed
by CHLID (yet).
RHASH ( %LID --> hxs )
Recall hash table; get a pointer to the hash table of a library.
RLINK ( %LID --> hxs )
Recall link table; get a pointer to the link table of a library.
RCFG ( %LID --> ob )
Recall config code; get a pointer to the config code of a library.
RMSG ( %LID --> arry )
Recall message table; get a pointer to the message table of a library.
RTITLE ( %LID --> $ )
Recall title; get the name of a library.
Note: RHASH, RLINK, RCFG, RMSG and RTITLE don't error if the library
associated to %LID didn't contain the requested item, they leave the
stack unchanged in that case.
RPORT ( %port --> ob1 .. obn )
Recalls pointers to all objects of a given port (0/1/2) onto the stack,
ignoring the R/W status of that port.
RLIB ( :%port:%LID --> lib )
( %LID --> libn %portn ... )
Recall lib; the 1st case recalls a library from a given port, the 2nd
case searches ports 0,1,2 for libraries with %LID, returning all found
libraries and the port numbers where they're stored.
Note: This command actually returns pointer to libraries (like RPORT),
if you recall a lib and try to purge it while it's on the stack, you'll
get a 'Object in use' error. Execute NEWOB or store it into a variable
first.
PGLIB ( :%port:%LID --> )
( %LID --> )
Purge lib; the 1st case works like :%port:%LID PURGE, in the 2nd case the
ports are searched in order 0,1,2 for an active library with %LID. The
difference to PURGE: if the library is attached to the home directory,
it's detached before purging. Also if there is an inactive library with
the same LID in any other port, it becomes active and is attached to the
HOME directory (if flag 5 is set, its config code is executed - see STLIB
below).
STLIB ( lib %port --> )
Store lib into port; there're a few differences to STO:
- The library is installed full; a warmstart isn't neccessary
and thus not initiated at the next power cycle. All warmstart
volatile variables (stack, PICT) remains intact.
- The library last stored is visible to the HP48 (in case of
having a library with the same LID installed in another port).
- If flag 5 is clear, the library is attached simply to the
home directory.
- If flag 5 is set, the config code of the library is executed
under warmstart conditions. Usefull for testing a config code.
ACLIB ( :%port:%LID --> )
Activate library. You can install libraries with the same LID in different
ports, but only one will be visible to the HP48 at the time. During
warmstarts the ports are searched in order 2,1,0 (most cases), ie. the
library stored in the port with the highest number will be active.
ACLIB allows you to switch to any other library with the same LID at
runtime, the effect is immidiate. ACLIB 1st detaches the LID from HOME,
sets the new priority and than a) attaches the LID to HOME again if flag
5 is clear, or b) runs the library config code if flag 5 is set (see STLIB
above).
LIBp ( %LID --> $ )
Returns a detailed layout of a library. The map starts with the title (if
exist), followed by the 1st and last address of the lib and the LID. The
remainder lists the contens of the lib, one line of information for each
XLIB entry. Structure of a line:
1st last xn name typ
||| |||| || |||| +++- Type of the object
||| |||| || ++++------ Name of the object (if it's a visible cmd)
||| |||| ++----------- XLIB number of the object
||| ++++--------------- Last relative address of the object
+++-------------------- Offset to startaddr. of the object
The list is sorted by offset. Try 1221 LIBp or 2 LIBp.
Note: If you find unexpected 'holes' between two XLIBs (> 10 nibbs) or
XLIBs embedded in other XLIBS, the library wasn't generated using
USRLIB.EXE or D->LIB; do not use D->LIB for recreating it because the
'holes' can hold essential data..
INSTp ( --> { %LIDn .. %LID1 } )
Returns a list of all libraries attached to the current directory, { } if
none.
Note: You can PURGE libraries even if they are attached to a subdirectory.
INSTp can be used to find such zombies references.
LIBSp ( --> { %LID1 .. %LIDn } )
Returns a list of all libraries currently installed on your HP48.
Note: We didn't use the '?' postfix because normally it marks a routine
for returning a flag in RPL. The JARGON file, v2.9.9, 01 APR 1992 states:
3. The `-P' convention: ------------------------ Turning a word into
a question by appending the syllable `P'; from the LISP convention of
appending the letter `P' to denote a predicate (a boolean-valued
function). The question should expect a yes/no answer, though it
needn't. (See {T} and {NIL}.)
At dinnertime:
Q: "Foodp?"
A: "Yeah, I'm pretty hungry." or "T!"
At any time:
Q: "State-of-the-world-P?"
A: (Straight) "I'm about to go home."
A: (Humorous) "Yes, the world has a state."
so we used 'p' for marking routines returning information ;-)
fEVAL ( ob --> ? )
Works like EVAL, but switches the display off 1st. Speeds up evaluation
for ~11%. In case of an error or the ob have fineshed execution, the
display is switched on again. Not very usefull, if ob prompts for input..
3.5 Things to Notice
--------------------
+---------------------------------------------------+
| HP 48 Resource Allocation Guideline: Library ID's |
+---------------------------------------------------+
| 0000 - 0256 Take-over libraries; do not use! |
| 0257 - 0512 HP ROM-based libraries; do not use! |
| 0513 - 0768 HP RAM-based libraries; do not use! |
| 0769 - 1791 3rd Party (assigned by HP) |
| 1792 - 2047 Command-line; do not use! |
+---------------------------------------------------+
*Don't use the following LIDs*, they're handled special by the HP48:
LID What's special ?
--- ----------------
240-255 ROMPTR@ assumes that the associated library command is in the
hidden ROM.
0-256,1792 The central routine to compile IDs (PTR 7BFD) returns pointer
instead of XLIBs.
The library stucture is 'flat', so don't try to include subdirectories in a
library, it can end up in a memory lost.
Not all program objects that execute correctly from global variables are
directly convertible into libraries. Here are some pitfalls:
- Since a library cannot be modified, no library command may be the
target of a STO or PUT operation.
- XLIB names are not usable in all contexts in which global names are
valid arguments. This can cause constructs that reference a named
object to fail. For example,
'A' 5 GETI
where A is a list will not work when A is converted to an XLIB name.
Instead use
A 5 GETI
- XLIB names are not valid as formal variables in algebraics, or as the
independent variable for plotting or solving.
- \->STR applied to a global name that is converted to a 'hidden' library
command (see $HIDDEN) returns a null string.
If any visible command starts with the seqence '\<< \->' or '\->' it's marked
in the library as a valid command for algebraics. If you press its associated
softkey in ALG entry mode, you'll get 'name()'.
Multiple occurences of variable names results in an incorrect library because
only the contens of the 1st one is picked up.
D->LIB needs ~(1.2 * size_of_source_directory) bytes to be free to generate a
library.
The time D->LIB needs for doing a job depends mainly on the total number of
commands included in the resulting library. Eg. Raymond runs D->LIB on a ~60kb
directory containing ~300 variables; D->LIB needs ~45min on a rev A HP48 to
make the library (not in FAST-mode).
Reassembling a splitted library may be dangerous if the original library was
not generated using USRLIB.EXE or D->LIB. There is no guarantee that the
result will work probably - even if no code changes are done.
USRLIB.EXE generates a link table entry for the configuration program; if you
split such a library with L->DIR, you'll get the configuration code twice, the
1st one stored in $CONFIG, the 2nd one stored in a variable of the generated
directory. Purge the variable before using D->LIB. You also can use LIBp to
see the second reference to the config code.
Appendix A - Quick Reference Guides
===================================
A.1 <-RPL->
-----------
A.1.1 Commands
--------------
Page 1234.1
RPL-> ( ob --> $ ) decompile object
->RPL ( $ --> ob ) compile object
DCADR ( hxs --> $ hxs' ) decompile one word
COD-> ( code --> $ ) disassemble CODE
->COD ( $ --> code libdat ) assemble CODE
->OB ( ob --> ob' )
Page 1234.2
DAN ( hxs %n --> $1 .. $n hxs' ) disassemble n times
DA1 ( hxs --> $ hxs' ) disassemble one mnemo
DAXY ( hxs hxs --> $ ) disassemble block
SYM-> ( libdat --> $ ) convert symbol table
$-> ( $ --> ob ) hex-dump to object
->$ ( ob --> $ ) object to hex-dump
Page 1234.3
EC ( --> ? ) entries catalog
E<->A ( hxs | $name --> $name | hxs ) get name/address
RPLtab ( --> $ ) recall ref. table
4/5/7 ( --> ) sys-stack display
CC ( --> ? ) character set catalog
A.1.2 Flag Usage
----------------
General:
Flag Meaning
---- -------
-4 If set, RPL->/DCADR are using the disassembler to decompile
code objects. Unresolved entries are generated as 'ASSEMBLE
\n\tCON(5)\t#xxxxx\nRPL' instead of 'PTR xxxxx'.
-13 Quiet mode if set. The status report of RPL->, ->RPL, COD->
and ->COD is suppressed.
-27 Set by 4/5/7 to signal an active medium font display. Can
be cleared to quit the sys-stack.
-28 Toggles sys-stack between 5/7 lines mode.
-29 Toggles the behaivior of the down arrow key during sys-stack
display and the EDIT menu key during the sys-i-stack. If set,
you can edit objects in sys-RPL syntax. A menu toggle for this
flag can be found on the 3rd page of the i-stack menu (labeled
SYS).
DAN and DA1 are using the following flags:
Flag (set) Meaning
---------- -------
1 next instr is a GO/RET YES/NO
2 last instr was RET...
3 last instr was GO C/NC/TO
4 last instr was relative GOSUB
5 last instr was absolute GO
6 last instr was PC manipulation
7 used internaly
8 last instr was absolute GO or Dx=(5)
A.1.3 Error Messages
--------------------
General Errormessages:
"Missing Library"
Requests to execute a command when the <-RPL-> library is not attached
to the HOME directory will cause this error.
"Need Binary Number"
The object passed to DCADR or DA1 isn't a binary number.
"Need String"
The object passed to ->RPL, ->COD or $-> isn't a string.
"Data Modifies Stack"
The object stored as RPL.TAB or ECpar doesn't add one item to the
stack.
"Where's your Program ?"
The string passed to ->RPL results to nothing.
"Primitive Code Object"
The object passed to RPL-> or the address passed to DCADR points to
a PCO.
->COD Errormessages:
->COD generates error messages of the following form:
"->COD Error: Pos x:yy
Message"
where 'x' is the INCLUDE nesting depth and 'yy' is the character offset of
the first character following the token that caused the error. 'Message'
may be one of the following:
"ENDIF Expected" an IF isn't matched by an ENDIF
"ENDIF w/o IF" missplaced ENDIF
"ELSE w/o IF" missplaced ELSE
"Invalid Parameter" invalid parameter field
"Inv. Expr" invalid parameter field expression
"Invalid Mnemonic" invalid menemonic
"Duplicate Label" double defined label
"GOYES/RTNYES Expected" comparisation without a following
conditional jump
"GOYES out of range" jump destination is more than -128/+127
nibbles away
"Parameter Expected" parameter of a mnemonic which expects
one is missing
"Unknown Symbol" unknown symbol in an expression
"Invalid String" invalid string constant
"No IF Nesting Yet" nesting of conditional IF .. ELSE .. ENDIF
structures is not allowed (yet).
->RPL Errormessages:
->RPL generates error messages of the following form:
"->RPL Error: Pos x:yy
Message"
where 'x' is the INCLUDE nesting depth and 'yy' is the character offset of
the first character following the token that caused the error. 'Message'
may be one of the following (additional to the ones listed for ->COD):
"; or } Expected"
Missing a ; to terminate a program, list, UNIT or SYMBOL
") Expected"
Missing a ) to terminate a comment
"" Expected"
Missing a " to terminate a string
"Misplaced ; or }"
Found a ; or } without a opening ::, {, UNIT or SYMBOL
"Suspect %"
"Suspect %%"
Parsing of a number results in an object of incorrect type.
"Body Len <> Datalen"
The length field of a HXS-like styled statement is not equal to
the data length
"More Tokens Expected"
The statement at the end of the input string is incomplete
In the following messages 'ttt' represents the token that causes the
error:
"ROMP LibID >FFF: ttt"
"ROMP ROMWD >FFF: ttt"
The library ID part or the ROM word number part of a ROMPTR statement
is > FFF
"Suspect \ Seq: ttt"
The escape sequence ttt in the string, ID or LAM is incomplete or
invalid
"Can't INCLUDE: ttt"
"Can't INCLOB: ttt"
There's no variable with the name ttt
"Inv. xxx: ttt"
where 'xxx' is one of the following:
"Tok" - ttt is unresolvable
"#" - ttt is out of range or contains other chars than hex digits
"$" - ttt doesn't start with a "
"%","%%"- ttt represents not a valid number
"PTR" - ttt is out of range or contains other chars than hex digits
"CHR" - ttt contains more than one char
"Body Dat" - the data field of a HXS-like styled statement contains
other chars than hex digits
"Body len" - the length field of a HXS-like styled statement contains
other chars than hex digits
"ROMP RW" - the ROM word number field of a ROMPTR is longer than 5
chars or contains other chars than hex digits
"ROMP LI" - the library ID field of a ROMPTR is longer than 5 chars
or contains other chars than hex digits
A.2 <-LIB->
===========
A.2.1 Commands
--------------
Page 1221.1
D->LIB ( --> lib ) build library
L->DIR ( % --> dir ) split library
MCFG ( --> ) make config program
ML->D ( --> prg ) make libdat-> handler
MD->L ( --> prg ) make ->libdat handler
OB-> ( ob --> ? ) split object
Page 1221.2
->DIR ( meta(ob,id) --> dir ) make directory
->PRG ( meta(ob) --> prg ) make program
->XLIB ( % % | # # --> xlib ) make XLIB
->ARR ( meta(ob) --> arry ) make array
->ALG ( meta(ob) --> alg ) make algebraics
->LD ( {} % --> libdta ) make library data
Page 1221.3
->BAK ( ob $ --> bak ) make backup
->ID ( $ --> id ) make identifier
ADRp ( ob --> ob # ) get address of object
$romid ( --> id ) get id '$ROMID'
$visible ( --> id ) get id '$VISIBLE'
$title ( --> id ) get id '$TITLE'
Page 1221.4
$config ( --> id ) get id '$CONFIG'
$vars ( --> id ) get id '$VARS'
$hidden ( --> id ) get id '$HIDDEN'
$message ( --> id ) get id '$MESSAGE'
LBCRC ( lib | bak --> lib' | bak' ) recalculate CRC
RNLIB ( lib $ --> lib' ) rename library
Page 1221.5
CHLID ( lib % --> lib' ) change LID
RHASH ( % --> C# ) get hash table
RLINK ( % --> C# ) get link table
RCFG ( % --> prg ) get config code
RMSG ( % --> arry ) get message table
RTITLE ( % --> $ ) get title
Page 1221.6
RPORT ( % --> ob ... ) recall port
RLIB ( % --> lib % ... ) recall library(s)
PGLIB ( % | :%:% --> ) purge library
STLIB ( lib % --> ) store library
ACLIB ( :%:% --> ) activate library
LIBp ( % --> $ ) get library layout
Page 1221.7
INSTp ( --> {} ) get installed LIDs
LIBSp ( --> {} ) get all LIDs on 48
fEVAL ( ob --> ? ) fast EVAL
A.2.2 Flag Usage
----------------
5 Set: STLIB executes config code of passed library after
installation.
ACLIB executes config code of activated library.
<-LIB->s config code displays (c) notice.
Clear: STLIB and ACLIB simply attaches handled library to
the HOME directory.
<-LIB->s config code don't display (c) notice.
6 Set: L->DIR places the $control variables at the end of the
generated directory.
Clear: L->DIR places the $control variables at the beginning of
the generated directory.
7 Set: L->DIR generates a $HIDDEN but no $VISIBLE variable.
Clear: L->DIR generates a $VISIBLE but no $HIDDEN variable.
-13 Set: D->LIB/L->DIR are switching the display off while processing
a directory/library (fast mode).
Clear: D->LIB/L->DIR are leaving the display on while working.
A.2.3 Error Messages
--------------------
"Missing $ROMID"
$ROMID is not defined in the current directory
"$ROMID Not Real/Binary"
$ROMID doesn't contain a real or binary object
"$ROMID Out of Range"
a) The value of $ROMID is > 2047
b) A real > 2047 was passed to CHLID
"$CONFIG Not a Program"
Because the stack must not change during warmstarts, $CONFIG must contain
a program
Note: Use 1 ->PRG to embedd CODE, IDs or XLIBs into a program.
"$HIDDEN Not a List"
"$VISIBLE Not a List"
"$VARS Not a List"
"$MESSAGE Not a List"
$XXX must contain a list
"Found ID Name>16 Chars"
D->LIB have found a visible command name which is > 16 chars in size
"Found 0-ID"
D->LIB have found a visible command name with the size 0
Appendix B - A ->COD Example
============================
Key in the following text (including the string delimiters) on your HP48 (you
may leave out the comments):
" GOSBVL =SAVPTR ** Save RPL pointers in save locations
** P is 0 , HEX mode enabled
LAHEX 123AFE ** Load HEX nibbles into A Register
** starting at P
P= 5 **
GOVLNG =PUSHhxsLoop ** Push A[WP] onto Data stack
** and pass control to RPL
"
Store it in the variable SRC1. Recall the text to the stack, then press
[->COD]. The display will show 'ASSEMBLER PASS 1' on the bottom line.
In the upper part of the display 'Line nnn' will appear, where <nnn>
represents the actual code line to be assembled (empty lines or comment
lines are not counted).
A second later the display will show 'ASSEMBLER PASS 2' on the bottom line and
'Processing nnn Lines' in the message area. Another second later the source
will have been assembled and the the string will be replaced by a 'Code'
object and a 'Library Data' object. The stack should look as follows:
+---------------------+
| |
+---------------------+
|4: |
|3: |
|2: Code|
|1: Library Data|
### ### ### ### ### ###
+---------------------+
The Library Data object contains all used local symbols (eg. labels). For the
above example, it is an empty string as there are no local symbols. The Code
object represents the assembled source text. DROP the Library Data object and
store the Code object into 'XQ1', then press the menu key [XQ1] . The stack
now looks like:
+---------------------+
| |
+---------------------+
|4: |
|3: |
|2: |
|1: # 123AFEh|
### ### ### ### ### ###
+---------------------+
Now lets change example 1 to make use of the symbolic facilities of SASM48.
First recall [SRC1] and edit the string:
"
hexdig EQU #123AFE
pHXS EQU 5
GOSBVL =SAVPTR ** Save RPL pointers in save locations
** P is 0 , HEX mode enabled
LA(6) hexdig ** Load 6 HEX nibbles (represented by hexdig)
** into A Register , starting at P
P= pHXS ** Set P to the value specified by pHXS
GOVLNG =PUSHhxsLoop ** Push A[WP] onto Data stack
** and pass control to RPL
"
Store the string in SRC2, recall it back to the stack, then press [->COD]. The
result looks like the result of example 1 except that the Library Data now
contains the values of the defined labels. When the stack shows:
+---------------------+
| |
+---------------------+
|4: |
|3: |
|2: Code|
|1: Library Data|
### ### ### ### ### ###
+---------------------+
press [SYM->] (located on the second menu page). The display changes to:
+---------------------+
| |
+---------------------+
|4: |
|3: |
|2: Code|
|1: "hexdig EQU #..|
### ### ### ### ### ###
+---------------------+
Press the down-arrow key:
+---------------------+
| prg|
+---------------------+
| |
| |
|"hexdig EQU #123..|
|pHXS EQU #5 |
### ### ### ### ### ###
+---------------------+
This is the symbol table for SRC2. Press ATTN to return to the stack. DROP the
string in level 1 and store the Code object into 'XQ2'. Press [XQ2]. You will
get the same result as in example 1 because it's the same machine language
program.
You could even use [COD->] to disassemble the Code object in level 1.
Appendix C - Ordering Information
=================================
The sources of the <-RPL-> and the <-LIB-> libraries consists of more than
15000 lines of RPL/assembler code (that's more than 250kb of text !) and we
spend our free time of more than one year on writing RPL48, so we decided to
release this version as GiftWare and probably the first non-beta version as
ShareWare.
Anyway, this release is a GiftWare release, ie. you can use RPL48 as long as
you like but only for developing non-comercial software and as a private
person. If you think RPL48 is usefull and the authors are worth to be rewarded
for the time they have invested in developing this toolkit, feel free to send
one of us (or both ;-) any sort of gift (even only a postcard will be wellcome).
If your gift covers the expense sending you a disk via SnailMail (costs are:
the disk, an envelope, the stamp and our time -> ~20$ or something equivalent),
we will send you the latest version of RPL48 on a MesS-DOS formatted disk
(including the <-RPL-> library branded with your name in the startup message).
Don't forget to include your name, address and the disk size you prefer.
Developing commercial software using RPL48 requires registration via the
GiftWare concept; companies have to send us at least a 50$-worth gift for
registration.
Planned for the future are:
- ROM rev J support (if there are problems)
- better ARRY support in <-RPL->
- maybe a DIR support in <-RPL->
- a system RPL debugger (hairy)
- a MKROM command which will allow a library creation similar to
MAKEROM.EXE
- a string editor (hairy)
- support of the new HP calc...
(all without guaranteeing the implementation)
Contact addresses:
Detlef Mueller Raymond Hellstern
Bellerbek 33 Liebigstr. 8
W-2000 Hamburg 56 W-3000 Hannover 1
Germany Germany
Tel. +49 40 811 92 80 Tel./FAX +49 511 66 10 11
e-mail: detlef@dmhh.hanse.de
--